//
// Copyright (C) OpenSim Ltd.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, see <http://www.gnu.org/licenses/>.
//
#ifndef __INET_LIFECYCLECONTROLLER_H
#define __INET_LIFECYCLECONTROLLER_H

#include "inet/common/INETDefs.h"
#include "inet/common/lifecycle/ILifecycle.h"


namespace inet {

/**
 * Manages operations like shutdown/restart, suspend/resume, crash/recover
 * and similar operations for nodes (routers, hosts, etc), interfaces, and
 * protocols.
 * @see ILifecycle, LifecycleOperation
 */

class INET_API LifecycleController
{
  protected:
    class INET_API Callback : public IDoneCallback
    {
      public:
        LifecycleController *controller = nullptr;
        LifecycleOperation *operation = nullptr;
        cModule *module = nullptr;

        void init(LifecycleController *controller, LifecycleOperation *operation, cModule *module);
        virtual void invoke() override;
    };

    Callback *spareCallback = nullptr;

  protected:
    virtual bool resumeOperation(LifecycleOperation *operation);
    virtual void doOneStage(LifecycleOperation *operation, cModule *submodule);
    virtual void moduleOperationStageCompleted(Callback *callback);    // invoked from the callback

  public:
    LifecycleController() : spareCallback(nullptr) {}
    virtual ~LifecycleController() { delete spareCallback; }

    /**
     * Initiate an operation. See the class documentation and ILifecycle for
     * details. The target module will be taken from the operation object.
     *
     * The return value indicates whether the operation has been completed
     * inside the call (true), or is pending because it will take several
     * events and likely nonzero simulation time to complete (false).
     * In the latter case, and if you provided a completionCallback as
     * parameter, you will be notified via the callback when the operation
     * completes.
     */
    virtual bool initiateOperation(LifecycleOperation *operation, IDoneCallback *completionCallback = nullptr);
};

} // namespace inet

#endif // ifndef __INET_LIFECYCLECONTROLLER_H

